#include "hook.h"

bool HookData::init(void* src, void* dst)
{
  func = (FARPROC) src;
  hookFunc = (FARPROC) dst;

  DWORD oldProtect;
  if (!VirtualProtect(func, 14, PAGE_EXECUTE_READWRITE, &oldProtect))
    return false;
  memcpy(data, func, 14);
  //VirtualProtect(func, 14, oldProtect, &oldProtect);
  hook();
  return true;
}
void HookData::hook()
{
  if (hooked || func == NULL) return;
  ptrdiff_t offset = ptrdiff_t(hookFunc) - ptrdiff_t(func) - 5;
  DWORD oldProtect;
#ifdef _WIN64
  is64 = (offset > 0x7FFF0000);
  if (is64)
  {
    BYTE* data = (BYTE*) func;
    VirtualProtect(func, 14, PAGE_EXECUTE_READWRITE, &oldProtect);
    *data++ = 0xFF;
    *data++ = 0x25;
    *(DWORD*) data = 0;
    *(FARPROC*) (data + 4) = hookFunc;
    //VirtualProtect(func, 14, oldProtect, &oldProtect);
  }
  else
#endif
  {
    BYTE* data = (BYTE*) func;
    VirtualProtect(func, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
    *data++ = 0xE9;
    *(DWORD*) data = DWORD(offset);
    //VirtualProtect(func, 5, oldProtect, &oldProtect);
  }

  hooked = true;
}
void HookData::unhook()
{
  if (!hooked || func == NULL) return;
  int count = (is64 ? 14 : 5);
  DWORD oldProtect;
  VirtualProtect(func, count, PAGE_EXECUTE_READWRITE, &oldProtect);
  memcpy(func, data, count);
  //VirtualProtect(func, count, oldProtect, &oldProtect);
  hooked = false;
}
